#ifndef UTILITY_DUKPT_H_
#define UTILITY_DUKPT_H_

#include <stdint.h>
#include "config.h"

#ifdef CONFIG_KEYCKS_CRC
#define key_cks(p)    crc7(0, p, 16)
#else
#define key_cks(p)    lrc(0, p, 16)
#endif

#define dukpt_cks(p)    key_cks(p)

typedef uint8_t future_key_t[16 + 1];   /* 16 bytes key, 1 byte checksum */
typedef uint32_t shift_reg_t;

#define inc_shift_reg(sf, n)    (sf = (sf + n) & 0x1FFFF)
#define left_shift_reg(sf, n)   (sf = (sf << n) & 0x1FFFF)

#define clear_ecnryption_counter(ksn)  do { \
                ksn[9] = 0; \
                ksn[8] = 0; \
                ksn[7] &= 0xE0; \
        }while (0)
#define extract_encryption_counter(ksn) \
        (ksn[9] + (ksn[8] << 8) + ((ksn[7] & 0x1F) << 16))

#define combine_encryption_counter(ksn, ec) do { \
                ksn[9] = ec & 0x0ff; \
                ksn[8] = (ec >> 8) & 0x0ff; \
                ksn[7] |= (ec >> 16) & 0x01f; \
        }while (0)

#define KSN_TYPE_NO			0xFF

#define DUKPT_MAGKEY_XOR	"\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
#define DUKPT_MAGKEY_XORLEN    16

#define DUKPT_MACKEY_XOR	"\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00"
#define DUKPT_MACKEY_XORLEN		16

#define DUKPT_PINKEY_XOR	"\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF"
#define DUKPT_PINKEY_XORLEN		16

#endif /* UTILITY_DUKPT_H_ */
